<?php
/**
 * jishupu-cms
 * @Author:技术铺
 * @Date:2021/11/22
 */

namespace App\Services;

use App\Models\User;
use App\Models\UserRole;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

/**
 * 管理员模块服务层
 *
 * Class UserService
 * @package App\Services
 */
class UserService
{
    /**
     * 系统管理员ID集
     * @return mixed
     */
    public static function systemAdminIdList()
    {
        return user::where('sys', '=', 1)->pluck('id')->toArray();
    }

    /**
     * 是否是系统管理员
     * @param int $user_id 管理员ID
     * @return bool
     */
    public static function isSys($user_id = 0)
    {
        return in_array($user_id > 0 ? $user_id : Auth::id(), self::systemAdminIdList());
    }

    /**
     * 更新或创建管理员信息，同时更新管理员角色关联表以及附件信息
     *
     * @param $user // 创建场景时，设置为null
     * @param array $data
     * @return bool
     */
    public static function updateOrCreate($user = null, $data = [])
    {
        if (empty($data)) return false;
        $role_ids = $data['role_ids'];
        unset($data['role_ids']);
        if ($user == null) {
            $data['password'] = Hash::make($data['password']);
            $user = new User($data);
            $user->save();
        } else if ($user instanceof User) {
            if (!empty($data['password'])) {
                $data['password'] = Hash::make($data['password']);
            } else {
                unset($data['password']);
            }
            $user->update($data);
        } else {
            return false;
        }

        // role_ids当前库对比当前提交，不同的则删除，一致则不更新
        $current_role_ids = $user->userRole()->pluck('role_id');
        $deleting_diff_role_ids = collect($current_role_ids)->diff($role_ids)->all();
        $inserting_diff_role_ids = collect($role_ids)->diff($current_role_ids)->all();
        if (!empty($deleting_diff_role_ids)) {
            UserRole::where('user_id', '=', $user->id)->whereIn('role_id', $deleting_diff_role_ids)->delete();
        }
        // role_ids当前提交对比当前库，不同的则写入，一致则不更新
        if (!empty($inserting_diff_role_ids)) {
            $user_role_data = collect($inserting_diff_role_ids)->map(function ($role_id) use ($user) {
                return [
                    'user_id' => $user->id,
                    'role_id' => $role_id,
                    'created_user_id' => $user->created_user_id,
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ];
            })->toArray();
            DB::table('user_role')->insert($user_role_data);
        }
        // 绑定附件表
        AttachmentService::bind($user, 'avatar_image', $user->avatar_image);
        return true;
    }


    /**
     * 判断是否超登录错误次数
     * @return bool
     */
    public static function validateLoginFailTimes(User $user)
    {
        if ($user->sys == 1) return true;
        $config_fail_times = ConfigService::getConfigItemValue('login', 'fail_times');
        if (empty($config_fail_times)) {
            return true;
        }
        $login_fail_times = CacheService::getCache($user->id . '_login_fail_times') ?: 0;
        return !($login_fail_times >= $config_fail_times);
    }

    /**
     * 记录登录错误次数
     * @param User $user
     * @return bool
     */
    public static function recordLoginFailTimes(User $user)
    {
        if ($user->sys == 1) return true;
        $config_fail_times = ConfigService::getConfigItemValue('login', 'fail_times');
        if (!empty($config_fail_times) && $config_fail_times > 0) {
            $login_fail_times = CacheService::getCache($user->id . '_login_fail_times');
            $value = !$login_fail_times ? 1 : ++$login_fail_times;
            if ($value <= $config_fail_times) {
                $expire = ($value == $config_fail_times) ? (new Carbon)->diffInSeconds(Carbon::tomorrow(), false) : 0;
                CacheService::setCache($user->id . '_login_fail_times', $value, $expire);
                $user->login_fail_times = $value;
                $user->save();
            }
        }
    }

    /**
     * 登录错误次数提示语
     * @return array|false|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Translation\Translator|mixed|string|string[]|null
     */
    public static function loginFailTimesTips()
    {
        $config_fail_times = ConfigService::getConfigItemValue('login', 'fail_times');
        $message = ConfigService::getConfigItemValue('login', 'fail_times_notice');
        if (empty($message)) {
            return __('error_login_fail_times_tips', ['times' => $config_fail_times]);
        } else {
            return str_replace(array(':times'), array($config_fail_times), $message);
        }
    }

    /**
     * 清除登录错误次数
     * @param User $user
     * @param false $update_last_login_time 同时更新最近登录时间？默认否
     * @return bool
     */
    public static function clearLoginFailTimes(User $user, $update_last_login_time = false)
    {
        if (CacheService::getCache($user->id . '_login_fail_times')) {
            CacheService::clear($user->id . '_login_fail_times');
        }
        $user->login_fail_times = 0;
        if ($update_last_login_time == true) {
            $user->last_login_time = Carbon::now();
        }
        return $user->save();
    }

    /**
     * 更新个人资料
     * @param $user
     * @param array $data
     * @return false
     */
    public static function updateProfile($user, $data = [])
    {
        if (empty($data)) return false;
        if (!empty($data['password'])) {
            $data['password'] = Hash::make($data['password']);
        } else {
            unset($data['password']);
        }
        if ($user->sys == 1) {
            unset($data['name']);
        }
        if (!$user->update($data)) return false;
        // 绑定附件表
        AttachmentService::bind($user, 'avatar_image', $user->avatar_image);
        return true;
    }


}
